<template>
    <Category :disabled="isShowList"/>
    <el-card shadow="always" :body-style="{ padding: '20px' }" :style="{marginTop:'30px'}">
        <template #header v-if="isShowList">
            <el-button type="primary" size="default" @click="addAttr" :icon="Plus" :disabled="!category3Id">添加属性</el-button>
        </template>
        <el-table border stripe :data="attrList" v-if="isShowList">
            <el-table-column type="index" width="80" label="序号"/>
            <el-table-column label="属性名称" width="150" prop="attrName"></el-table-column>
            <el-table-column label="属性值名称列表">
                <template #="{row}">
                    <el-tag type="danger" size="default"  effect="dark " @close="" 
                        v-for="item in row.attrValueList" :key="item.id" :style="{marginRight:'10px'}"
                    >
                    {{item.valueName}}
                    </el-tag>
                </template>
            </el-table-column>
            <el-table-column label="操作" width="150">
                <template #="{row}">
                    <el-button type="warning" size="default" @click="updateAttr(row)" :icon="Edit"></el-button>
                    <el-popconfirm title="你真的要删除吗?" @confirm="deleteAttr(row)">
                            <template #reference>
                                <el-button type="danger" size="default" @click="" :icon="Delete"></el-button>
                            </template>
                    </el-popconfirm>
                </template>
            </el-table-column>
        </el-table>
        <div v-else>
            <el-form  :inline="true">
                <el-form-item label="属性名">
                    <el-input placeholder="请输入属性名" v-model="newAttrData.attrName"></el-input>
                </el-form-item>
            </el-form>
            <div>
                <el-button type="primary" size="default" @click="addAttrValue" :disabled="!newAttrData.attrName">添加属性值</el-button>
                <el-button type="default" size="default" @click="cancle">取消</el-button>
            </div>
            <el-table border stripe style="margin-top: 30px" :data="newAttrData.attrValueList">
                <el-table-column type="index" width="50" label="序号"/>
                <el-table-column label="属性值名称">
                    <template #="{row,$index}">
                        <el-input v-model="row.valueName" placeholder="请输入属性值名称" ref="inpEle" 
                        size="default"  @blur="changeToLook(row,$index)" v-if="row.isEdit" @focus="saveValueName(row)"></el-input>
                        <span v-else @click="changeToEdit(row)" :style="{display: 'inline-block',width: '70%'}">{{row.valueName}}</span>
                    </template>
                </el-table-column>
                <el-table-column label="操作">
                    <template #="{$index}">
                        <el-popconfirm title="你真的要删除吗?" @confirm="deleteAttrValue($index)">
                            <template #reference>
                                <el-button type="danger" size="default"  icon="ele-Delete"></el-button>
                            </template>
                        </el-popconfirm>
                    </template>
                </el-table-column>
            </el-table>
            
            <div style="margin-top: 30px;"> 
                <el-button type="primary" size="default" @click="saveAttr" 
                :disabled="newAttrData.attrValueList.length<=0 || !newAttrData.attrName">保存</el-button>
                <el-button type="default" size="default" @click="cancle">取消</el-button>
            </div>
        </div>
    </el-card>
    
</template>

<script lang="ts">
import { defineComponent } from "vue";
import { ElMessage } from 'element-plus'

export default defineComponent({
    name: "Attr",
});
</script>

<script setup lang="ts">
    import {Plus,Edit,Delete} from '@element-plus/icons-vue'
    import {watch,ref,nextTick} from 'vue'
    import useAttrStore from '@/stores/attr'
    import {storeToRefs} from 'pinia'
    import type {reqAttrReturnType,reqAttrReturnItemType,reqAtrrReturnAttrValueType} from '@/api/attr'
    import {requestAtrrInfo,requestUpdateOrAddAttr,requestDeleteAttr} from '@/api/attr'
    import cloneDeep from 'lodash/cloneDeep'

    const attrStore = useAttrStore()
    const {category1Id,category2Id,category3Id} = storeToRefs(attrStore)

    const attrList = ref<reqAttrReturnType>([])

    //获取属性列表
    const getAttrList = async () => {
        const re = await requestAtrrInfo(category1Id.value as number, category2Id.value as number, category3Id.value as number)
        attrList.value = re
    }
    //监听三级分类的id改变，发送请求
    watch(category3Id,(newValue) => {
        //如果点击一级列表会清空其他数据，发请求会报错
        if(!newValue){
            attrList.value = []
            return
        }
        //发送请求
        getAttrList()
    },{immediate:true})

    //1.添加属性逻辑
    //定义一个初始化的新属性
    const newAttrData = ref<reqAttrReturnItemType>({
        attrName: '',
        categoryId: category3Id.value as number,
        categoryLevel: 3,
        attrValueList: []
    })
    //控制添加属性页面显示与隐藏
    const isShowList = ref(true)
    //2.点击添加属性
    const addAttr = () => {
        //清空修改属性残留的newAttrData
        newAttrData.value = {
            attrName: '',
            categoryId: category3Id.value as number,
            categoryLevel: 3,
            attrValueList: []
        }
        //显示添加属性页面
        isShowList.value = false
    }

    //3.点击添加属性值
    const addAttrValue = () => {
        //创建一个属性值
        const newAttrValue = ref<reqAtrrReturnAttrValueType>({
            valueName:'',
            attrId: newAttrData.value.id,
            isEdit: true
        })
        //添加到新属性的数组中
        newAttrData.value.attrValueList.push(newAttrValue.value)
        //添加属性时也要自动获取焦点
        nextTick(() => {
            inpEle.value.focus()
        })
    }
    
    //4.点击修改属性
    const updateAttr = (row:reqAttrReturnItemType) => {
        //显示修改属性页面
        isShowList.value = false
        //因为数据双向绑定，直接给new属性赋值，可以实现自动填入，因为对象地址一样，需要深拷贝，否则视图也会变
        const cloneData = cloneDeep(row)
        //遍历attrValueList添加isEdit默认不可编辑
        cloneData.attrValueList.forEach(item => {
            item.isEdit = false
        })
        newAttrData.value = cloneData
    }
    //点击取消
    const cancle = () => {
        //返回属性值列表
        isShowList.value = true
    }

    //input元素
    const inpEle = ref()
    //6.点击span改变成编辑模式
    const changeToEdit = (row:reqAtrrReturnAttrValueType) => {
        row.isEdit = true
        //自动获取焦点,因为数据更新不能操作真实dow，所以使用nextTick
        nextTick(() => {
            inpEle.value.focus()
        })
    }
    //定义全局保存旧值
    let oldValueName = ''
    //获取焦点时保存旧值
    const saveValueName = (row:reqAtrrReturnAttrValueType) => {
        oldValueName = row.valueName
        console.log(oldValueName);
    }
    //7.input失去焦点变成不可编辑模式
    const changeToLook = (row:reqAtrrReturnAttrValueType,$index:number) => {
        row.isEdit = false
        //判断用户输入是否为空
        if(!row.valueName.trim()){
            //判断是否有旧值，有代表修改，不可能是新增
            if(oldValueName){
                //把旧值重新赋值给他
                row.valueName = oldValueName
            }else{//没有旧值就是新增删除他
                newAttrData.value.attrValueList.splice($index,1)
            }
        }
        //判断输入是否重复
        const isReset = newAttrData.value.attrValueList.some(item => {
            //不能自己和自己比较
            if(item === row) return
            return item.valueName === row.valueName
        })
        //如果重复
        if(isReset){
            //判断有无旧值
            if(oldValueName){
                row.valueName = oldValueName
            }else{
                newAttrData.value.attrValueList.splice($index,1)
            }
        }
        //无论怎样，必须清空旧值
        oldValueName = ''
    }

    //删除当前的属性值
    const deleteAttrValue = ($index:number) => {
        newAttrData.value.attrValueList.splice($index,1)
    }
    //点击保存发送请求
    const saveAttr = async() => {
        //在保存值的时候删除isEdit
        newAttrData.value.attrValueList.forEach(item => {
            delete item.isEdit
        })
        //判断当前属性值列表是否为空
        if(newAttrData.value.attrValueList.length <= 0){
            ElMessage.error('不能提交空的属性列表')
            return
        }
        try {
            await requestUpdateOrAddAttr(newAttrData.value)
            ElMessage.success('新增或修改成功')
            //重新回到属性列表
            isShowList.value = true
            //重新发送请求
            getAttrList()
        } catch (e) {
            ElMessage.error('新增或者修改失败')
        }
    }

    //删除当前的属性
    const deleteAttr = async (row:reqAttrReturnItemType) => {
        try {
            await requestDeleteAttr(row.id as number)
            ElMessage.success('删除属性成功')
            //重新发送请求
            getAttrList()
        } catch (e) {
            ElMessage.error('删除属性失败')
        }
    }
</script>